package jdklearning.function;


import java.util.concurrent.Callable;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;

/**
 * Java 8 中我们可以通过 `::` 关键字来访问类的构造方法，对象方法，静态方法。
 * 观察接口 IConvert，传参为类型 F，返回类型 T。所以，我们可以这样访问类Something的方法：
 *
 * 总结：我们可以把类Something中的方法static String startsWith(String s){...}
 * 、String endWith(String s){...}、Something(String something){...}看作是接口IConvert的实现
 * ，因为它们都符合接口定义的那个“模版”，有传参类型F以及返回值类型T。
 * 比如构造方法Something(String something)，它传参为String类型，返回值类型为Something。
 * 注解@FunctionalInterface保证了接口有且仅有一个抽象方法，所以JDK能准确地匹配到相应方法。
 *
 *
 * lambda表达式忽略接受参数对象类型 (see {@link #useIFunction(IFunction)} ()} userIFunction(Thread::new);

 * @author shenenlu 2021年05月17日 上午09:33:00
 */
public class FunctionLearning {

    static void staticMethods(){
        // static methods
        IConverter<String, String> converter = Something::startsWith;
        String converted = converter.convert("123");
        System.out.println(converted);
    }

    static void objectMethods(){
        // object methods
        Something something = new Something();
        IConverter<String, String> converter = something::endWith;
        String converted = converter.convert("Java");
        System.out.println(converted);
    }

    static void constructorMethods(){
        // constructor methods
        IConverter<String, Something> converter = Something::new;
        Something something = converter.convert("constructors");
        System.out.println(something);
    }


    static void userConverter(IConverter<String, String> converter){
        System.out.println(converter.convert("aaa"));
    }

    static void useIFunction(IFunction function){
        function.execute();
    }

    void useIFunction1(IFunction function){
        function.execute();
    }


    public void functionLambdaTest(){
        StaticUtil.useIFunctionStatic(Function2Enum.A::execute2);
        StaticUtil.useIFunctionStatic(Thread::new);
//        useIFunction1(IFunction2::execute2);
    }

    public static void main(String[] args) {

        /**
         *      JAVA	SUPPORTS EXCEPTIONS	 ARGUMENT	RETURNS	.NET EQUIVALENT
         *         Callable	         Yes	   No	     Yes	 Func
         *         Supplier	          No	   No	     Yes	 Func
         *         Function<T,R>	  No	     Yes	 Yes	 Func<T,R>
         *         Consumer	          No	     Yes	 No	 Action
         *         Runnable	          No	      No	 No	 Action
         */
        Callable callable;
        Supplier supplier;
        Function function;
        Consumer consumer;
        Runnable runnable;
        Predicate predicate;

        staticMethods();
        objectMethods();
        constructorMethods();

        IConverter<String, String> converter = string -> string;
        userConverter(converter);

        userConverter(form -> form);

        useIFunction(Thread::new);
    }

}


